﻿using System.Linq;
using CID.Domain.Infrastructure;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Persistence.Tests.Infrastructure
{
    [TestFixture]
    class DeploymentAgentPersistenceTests : BasePersistenceWithDataTests
    {
        private static void AssertAreEqual(DeploymentAgent expected, DeploymentAgent actual)
        {
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.Address, actual.Address);
            Assert.AreEqual(expected.Enabled, actual.Enabled);
            CollectionAssert.AreEquivalent(expected.Locations.Select(x => x.Id), actual.Locations.Select(x => x.Id));
        }

        [Test]
        public void SaveNewDeploymentAgent_DeploymentAgentShouldBeSaved()
        {
            var session = OpenSession();
            var newDeploymentAgent = DataProvider.CreateDeploymentAgent();
            session.SaveOrUpdate(newDeploymentAgent);
            CleanSession(session);

            Assert.AreNotEqual(NotSavedId, newDeploymentAgent.Id);
            session = OpenSession();
            var retrievedDeploymentAgent = session.Get<DeploymentAgent>(newDeploymentAgent.Id);
            AssertAreEqual(newDeploymentAgent, retrievedDeploymentAgent);
            CleanSession(session);
        }

        [Test]
        public void SaveModifiedDeploymentAgent_ChangesShouldBeSaved()
        {
            var session = OpenSession();
            var newDeploymentAgent = DataProvider.CreateDeploymentAgent();
            newDeploymentAgent.AddLocation(Operations.DataProvider.GetLocation(session, OperationsData.Location1));
            session.SaveOrUpdate(newDeploymentAgent);
            CleanSession(session);

            session = OpenSession();
            var modifiedDeploymentAgent = session.Get<DeploymentAgent>(newDeploymentAgent.Id);
            AssertAreEqual(newDeploymentAgent, modifiedDeploymentAgent); //Necessary to load lazy collections before the session is wiped out
            modifiedDeploymentAgent.ModifyProperty(x => x.Name);
            modifiedDeploymentAgent.ModifyProperty(x => x.Address);
            var version = Development.DataProvider.GetVersion(session, DevelopmentData.Component2UnreleasedVersion);
            modifiedDeploymentAgent.AddLocation(Operations.DataProvider.GetLocation(session, OperationsData.Location2));
            modifiedDeploymentAgent.ModifyProperty(x => x.Enabled);
            session.SaveOrUpdate(modifiedDeploymentAgent);
            CleanSession(session);

            session = OpenSession();
            var retrievedDeploymentAgent = session.Get<DeploymentAgent>(newDeploymentAgent.Id);
            AssertAreEqual(modifiedDeploymentAgent, retrievedDeploymentAgent);
            CleanSession(session);
        }

        [Test]
        public void DeleteDeploymentAgent_DeploymentAgentShouldBeDeleted()
        {
            var session = OpenSession();
            var newDeploymentAgent1 = DataProvider.CreateDeploymentAgent("Another Deployment Agent");
            var newDeploymentAgent2 = DataProvider.CreateDeploymentAgent();
            newDeploymentAgent1.AddLocation(Operations.DataProvider.GetLocation(session, OperationsData.Location1));
            session.SaveOrUpdate(newDeploymentAgent1);
            session.SaveOrUpdate(newDeploymentAgent2);
            CleanSession(session);

            session = OpenSession();
            var retrievedDeploymentAgent1 = session.Get<DeploymentAgent>(newDeploymentAgent1.Id);
            session.Delete(retrievedDeploymentAgent1);
            CleanSession(session);

            session = OpenSession();
            retrievedDeploymentAgent1 = session.Get<DeploymentAgent>(newDeploymentAgent1.Id);
            var retrievedDeploymentAgent2 = session.Get<DeploymentAgent>(newDeploymentAgent2.Id);
            Assert.IsNull(retrievedDeploymentAgent1);
            Assert.IsNotNull(retrievedDeploymentAgent2);
            CleanSession(session);
        }
    }
}
